﻿using Casamiel.API.Application.Models;
using Casamiel.API.Application.Services;
using Casamiel.Application;
using Casamiel.Common;
using Casamiel.Common.Extensions;
using Casamiel.Common.Utilities;
using Casamiel.Domain;
using Casamiel.Domain.Entity;
using Enyim.Caching;
using MediatR;
using Microsoft.Extensions.Options;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Linq;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;

namespace Casamiel.API.Application.Commands
{
    /// <summary>
    /// Gift card charge command handler.
    /// </summary>
    public sealed class GiftCardChargeCommandHandler : BaseCommandHandler, IRequestHandler<GiftCardReChargeCommand, Zmodel>
    {
        private readonly string _memcachedPrex;
        private readonly IMemcachedClient _memcachedClient;
        private readonly IPaymentService _paymentService;
        private readonly INetICService _netICService;
        private readonly IMemberCardService _memberCardService;
        private readonly IMemberService _memberService;
        /// <summary>
        /// 
        /// </summary>
        /// <param name="casamielSettings"></param>
        /// <param name="iicApiService"></param>
        /// <param name="memberCard"></param>
        /// <param name="memberService"></param>
        /// <param name="paymentService"></param>
        /// <param name="mobileCheckCode"></param>
        /// <param name="userLogService"></param>
        /// <param name="memcachedClient"></param>
        /// <param name="netICService"></param>
        public GiftCardChargeCommandHandler(IOptionsSnapshot<CasamielSettings> casamielSettings, IIcApiService iicApiService,
            IMemberCardService memberCard, IMemberService memberService, IPaymentService paymentService,
              IMobileCheckCode mobileCheckCode, IUserLogService userLogService, IMemcachedClient memcachedClient, INetICService netICService) : base(iicApiService, memberCard, memberService, mobileCheckCode, userLogService)
        {
            if (casamielSettings == null) {
                throw new ArgumentNullException(nameof(casamielSettings));
            }
            _paymentService = paymentService;
            _memcachedClient = memcachedClient;
            _memcachedPrex = casamielSettings.Value.MemcachedPre;
            _netICService = netICService;
            _memberCardService = memberCard;
            _memberService = memberService;
        }
        /// <summary>
        /// Handle the specified request and cancellationToken.
        /// </summary>
        /// <returns>The handle.</returns>
        /// <param name="request">Request.</param>
        /// <param name="cancellationToken">Cancellation token.</param>
        public async Task<Zmodel> Handle(GiftCardReChargeCommand request, CancellationToken cancellationToken)
        {
            if (request == null) {
                throw new ArgumentNullException(nameof(request));
            }

            const string pattern = "^[0-9]*$";
            Regex rx = new Regex(pattern);
            var isValid = rx.IsMatch(request.Qrcode); //bool类型
            if (!isValid) {
                return new Zmodel { code = 999, msg = "充值码格式不正确" };
            }

            var _cachekey = _memcachedPrex + Constant.ICQRCODEVERIFY + request.Mobile;
            var trynum = _memcachedClient.Increment(_cachekey, 1, 1);
            this.Logger.Trace($"GiftCardCharge,c_{request.Cardno},{_cachekey}_{trynum}");

            if (trynum > 1) {
                var cardinfo = await MemberCardService.FindAsync<ICasaMielSession>(request.Mobile, true).ConfigureAwait(false);// list.SingleOrDefault(c => c.CardType == $"{(int)CardType.Gift}");
                if (cardinfo != null) {
                    if (cardinfo.BindTime.Value.Minute == DateTime.Now.Minute) {
                        //_memcachedClient.Remove(_cachekey);
                        return new Zmodel { code = 0, msg = "处理成功", content = "" };
                    }
                }
                if (trynum > 14) {
                    _memcachedClient.Remove(_cachekey);
                } else {
                    return new Zmodel { code = 999, msg = "处理中。。。" };
                }

            }
            


             var cardNO = request.Cardno;
            var ar = await MemberCardService.FindAsync<ICasaMielSession>(request.Mobile, false).ConfigureAwait(false);
            var charagemoney = "";

            if (ar != null) {
                cardNO = ar.CardNO;
            } else {
                cardNO = "";
            }
            Logger.Trace($"icqrcodeverifyReq:{cardNO}||{request.Mobile}||{request.Qrcode}");
            var a = await IcApiService.IcqrcodeVerify(cardNO, request.Mobile, request.Qrcode, request.Source).ConfigureAwait(false);
            Logger.Trace($"icqrcodeverifyResult:{JsonConvert.SerializeObject(a)}");

            if (a.code == 0) {

                var jContent = JsonConvert.DeserializeObject<JObject>(a.content);
                if (jContent != null && jContent["chargemoney"] != null) {
                    charagemoney = $",充值金额：{jContent["chargemoney"].ToString()}";
                    try {
                        var payment = new PaymentRecord() {
                            Mobile = request.Mobile,
                            BillNO = jContent["cardno"].ToString(),
                            OperationMethod = 6,
                            Amount = jContent["chargemoney"].ToDouble(0),
                            CreateTime = DateTime.Now,
                            OutTradeNo = request.Qrcode,
                            TradeNo = $"C{Util.GenerateUniqueID()}",
                            PayMethod = (int)PayMethod.GiftRecharge,
                            OperationState = 1,
                            State = 1,
                            PayTime = DateTime.Now,
                            LastOperationTime = DateTime.Now
                        };
                        await _paymentService.AddAsync<ICasaMielSession>(payment).ConfigureAwait(false);
                    } catch (Exception ex) {
                        Logger.Error($"GiftCardCharge:{ex.StackTrace}");
                        await _memcachedClient.RemoveAsync(_cachekey).ConfigureAwait(false);
                        throw;
                    }

                }
                var member = await MemberService.FindAsync<ICasaMielSession>(request.Mobile).ConfigureAwait(false);
                if (member == null) {
                    member = new Member { Mobile = request.Mobile, Source = request.Source, CreateDate = DateTime.Now, LastLoginDate = DateTime.Now };
                    await MemberService.AddAsync<ICasaMielSession>(member).ConfigureAwait(false);

                }

                if (string.IsNullOrEmpty(cardNO)) {
                    if (a.content.Trim().Length > 0) {

                        //var rnt = JsonConvert.DeserializeObject<JObject>(a.content);
                        cardNO = jContent["cardno"].ToString();
                        var cardentity = await MemberCardService.FindAsync<ICasaMielSession>(cardNO).ConfigureAwait(false);
                        if (cardentity != null && cardentity.IsBind == false) {
                            await MemberCardService.DeleteByCardNO<ICasaMielSession>(cardNO).ConfigureAwait(false);
                            await UserLogService.AddAsync<ICasaMielSession>(new UserLog { OPInfo = "删除礼品卡,卡号:[" + cardNO + "]," + cardentity.Mobile, UserName = request.Mobile, Url = request.RequestUrl, UserIP = request.UserIP, OPTime = DateTime.Now }).ConfigureAwait(false);
                        }
                        ar = new MemberCard {
                            M_ID = member.ID, CardNO = cardNO,
                            CardType = $"{(int)CardType.ECard}",
                            IsBind = true, Source = request.Source,
                            BindTime = DateTime.Now, CreateTime = DateTime.Now,
                            Mobile = request.Mobile
                        };

                        await MemberCardService.AddAsync<ICasaMielSession>(ar).ConfigureAwait(false);
                        var cardlist = await MemberCardService.GetListAsync<ICasaMielSession>(request.Mobile).ConfigureAwait(false);
                        if (cardlist.Count(c => c.CardType == "2") > 1) {
                            await MemberCardService.DeleteByCardNO<ICasaMielSession>(cardNO).ConfigureAwait(false);
                            this.Logger.Trace($"GiftCardCharge:[{cardNO}]卡号重复申请");
                        }

                    } else {
                        Logger.Error($"出错了：icqrcodeverifyReq:{cardNO}||{request.Mobile}||{request.Qrcode}，{JsonConvert.SerializeObject(a)},");
                    }
                } else {
                    ar.CardType = $"{(int)CardType.ECard}";
                    ar.BindTime = DateTime.Now;
                    ar.IsBind = true;
                    await MemberCardService.UpdateAsync<ICasaMielSession>(ar).ConfigureAwait(false);
                }
                Task task = Task.Run(async () => {
                    await UserLogService.AddAsync<ICasaMielSession>(new UserLog { OPInfo = "礼品卡充值,卡号:[" + cardNO + "]" + charagemoney + ",qrcode:" + request.Qrcode, UserName = request.Mobile, Url = request.RequestUrl, UserIP = request.UserIP, OPTime = DateTime.Now }).ConfigureAwait(false);
                }, cancellationToken);
                 
                await _memcachedClient.RemoveAsync(_cachekey).ConfigureAwait(false);
            } else {
                await _memcachedClient.RemoveAsync(_cachekey).ConfigureAwait(false);
            }

            return a;
        }
    }
}
